import json
import os
import random
import re
import time
import os
from rest_framework import status
from rest_framework.permissions import AllowAny

from django.utils.decorators import method_decorator
from rest_framework.decorators import api_view, permission_classes
from rest_framework.generics import ListAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http import HttpResponse, HttpResponseRedirect
from django.core.cache import cache
import uuid
import requests
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt

import posts
from utils.image_uploader import image_uploader
from django.conf import settings

from user import models, userser
from utils.captcha import CaptchaGenerator
from utils.myRedis import myRedis, RedisClient
from utils.resume_word import generate_word_resume
from utils.send import send_message
from utils.JWTTool import jwtTool
from django.views import View
from django.http import JsonResponse
from io import BytesIO
import base64
import qrcode
from user.models import User, RealNameVerification, Role
from utils.baidu_ai import baidu_ai
from user.models import User, Role
# 七牛云上传回调接口
# 在 Django 的 views.py 中
from django.http import JsonResponse
from tools import tool_qiniu
from qiniu import put_file, put_data

# 导入帖子相关模型
from posts.models import Post, PostLike, PostStar
from django.db.models import Q  # 修正Q对象导入

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from utils.JWTTool import JwtUtils




class CaptchaView(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        try:
            # 生成验证码
            captcha = CaptchaGenerator()
            code, image_buffer = captcha.get_captcha()

            # 生成唯一标识
            captcha_key = request.query_params.get('captcha_key')
            if not captcha_key:
                return safe_response({'code': 400, 'msg': '缺少captcha_key'}, status=400)

            # 将验证码保存到redis缓存，设置有效期2分钟
            myRedis.set(captcha_key, code, 120)

            # 返回验证码图片和标识
            response = HttpResponse(image_buffer, content_type='image/png')
            response['X-Captcha-Key'] = captcha_key
            return response
        except Exception as e:
            import traceback
            print(traceback.format_exc())  # 控制台输出详细错误
            return safe_response({'code': 500, 'msg': '服务端异常', 'detail': str(e)}, status=500)


class SendCode(APIView):
    permission_classes = [AllowAny]
    def post(self, request):
        phone = request.data.get('phone')
        captcha_key = request.data.get('captcha_key')
        icode = request.data.get("icode")
        if not phone:
            return safe_response({'code': 400, 'msg': '手机号不能为空'})
        re_phone = re.match(r'^1[3-9]\d{9}$', phone)
        if not re_phone:
            return safe_response({'code': 400, 'msg': '手机号格式错误'})
        if not icode:
            return safe_response({'code': 400, 'msg': '验证码不能为空'})
        r_icode = myRedis.get(captcha_key)
        if not r_icode:
            return safe_response({'code': 400, 'msg': '图片验证码已过期'})
        elif r_icode != icode:
            return safe_response({'code': 400, 'msg': '图片验证码错误'})
        else:
            myRedis.delete(captcha_key)
        code = random.randint(1000, 9999)
        re_code = send_message(phone, code)
        if isinstance(re_code, str):
            try:
                res_code = json.loads(re_code)
            except Exception:
                return safe_response({'code': 400, 'msg': '发送失败'})
        else:
            res_code = re_code
        if res_code.get('statusCode') == '000000':
            myRedis.set(phone, code, 120)
            return safe_response({'code': 200, 'msg': '发送成功'})
        else:
            return safe_response({'code': 400, 'msg': '发送失败'})


from user.models import Role

class LoginByCode(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        phone = request.data.get('phone')
        code = request.data.get('code')
        if not phone:
            return safe_response({'code': 400, 'msg': '手机号不能为空'})
        if not code:
            return safe_response({'code': 400, 'msg': '验证码不能为空'})
        re_phone = re.match(r'^1[3-9]\d{9}$', phone)
        if not re_phone:
            return safe_response({'code': 400, 'msg': '手机号格式错误'})
        user = models.User.objects.filter(phone=phone).first()
        if not user:
            return Response({"code": 400, 'msg': '用户不存在'})

        r_code = myRedis.get(phone)
        if r_code != code:
            return safe_response({'code': 400, 'msg': '验证码错误'})
        token = jwtTool.generate_token(user.id)
        pyload = jwtTool.decode_token(token)
        pyload['exp'] = pyload['exp'] + 60 * 60 * 24
        retoken = jwtTool.encode(pyload)
        return safe_response(
            {'code': 200, 'msg': '登录成功', 'data': {'token': token, 'retoken': retoken, "userid": user.id}})


class RoleList(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        role = Role.objects.all()
        ser = userser.RoleSerializer(role, many=True)
        return Response({'code': 200, 'data': ser.data})


# 注册接口
class Register(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        phone = request.data.get('phone')
        code = request.data.get('code')
        if not phone:
            return Response({'code': 400, 'msg': '手机号不能为空'})
        if not code:
            return Response({'code': 400, 'msg': '验证码不能为空'})
        re_phone = re.match(r'^1[3-9]\d{9}$', phone)
        if not re_phone:
            return Response({'code': 400, 'msg': '手机号格式错误'})
        r_code = myRedis.get(phone)
        if r_code != code:
            return Response({'code': 400, 'msg': '验证码错误'})
        ser = userser.UserSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            token = jwtTool.generate_token(ser.data['id'])
            pyload = jwtTool.decode_token(token)
            pyload['exp'] = pyload['exp'] + 60 * 60 * 24
            retoken = jwtTool.encode(pyload)
            role_id = models.User.objects.filter(role_id=ser.data['role']).first()
            ser1 = userser.UserSerializer(role_id)
            print(ser1.data['role'])
            if ser1.data['role'] == 1:
                models.JobInfo.objects.create(user_id=ser.data['id'])
            else:
                models.HRInfo.objects.create(user_id=ser.data['id'])
            return Response(
                {'code': 200, 'msg': '注册成功',
                 'data': {'token': token, 'retoken': retoken, "userid": ser.data['id']}})
        else:
            return Response({'code': 400, 'msg': '注册失败'})



class Retoken(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        retoken = request.query_params.get('retoken')
        pyload = jwtTool.decode_token(retoken)
        pyload['exp'] = pyload['exp'] + 60 * 60 * 24 * 7
        token = jwtTool.encode(pyload)
        pyload = jwtTool.decode_token(token)
        pyload['exp'] = pyload['exp'] + 60 * 60 * 24
        retoken = jwtTool.encode(pyload)
        return safe_response(
            {'code': 200, 'data': {'token': token, 'retoken': retoken}})

# ========== QQ模拟登录相关视图 ==========

@method_decorator(csrf_exempt, name='dispatch')
class QQLoginView(View):
    """QQ模拟登录 - 生成二维码"""

    def get(self, request):
        # 直接生成前端首页URL，扫码后直接跳转
        frontend_home_url = "http://localhost:3000/"  # 请修改为您的Vue项目地址

        # 生成二维码
        qr = qrcode.QRCode(box_size=10, border=4)
        qr.add_data(frontend_home_url)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        buffer = BytesIO()
        img.save(buffer, format="PNG")
        img_str = base64.b64encode(buffer.getvalue()).decode()

        return JsonResponse({
            "qr_code": f"data:image/png;base64,{img_str}",
            "login_url": frontend_home_url,
            "msg": "QQ登录二维码已生成"
        })


@method_decorator(csrf_exempt, name='dispatch')
class QQSuccessView(View):
    """QQ模拟登录成功页面"""

    def get(self, request):
        # 获取默认角色
        default_role = Role.objects.first()
        if not default_role:
            return JsonResponse({
                "error": "系统错误",
                "msg": "请先在后台创建至少一个角色"
            }, status=500)

        # 生成模拟QQ用户信息
        mock_qq_user = {
            'openid': f'qq_openid_{random.randint(10000, 99999)}',
            'nickname': f'QQ用户{random.randint(1000, 9999)}',
            'avatar': 'https://qlogo.cn/qqapp/102795359/default/100'
        }

        # 创建或获取用户
        user, created = User.objects.get_or_create(
            openid=mock_qq_user['openid'],
            defaults={
                'username': mock_qq_user['nickname'],
                'role': default_role,
                'avatar': mock_qq_user['avatar']
            }
        )

        # 如果用户已存在但信息不完整，更新信息
        if not created:
            if not user.username:
                user.username = mock_qq_user['nickname']
            if not user.avatar:
                user.avatar = mock_qq_user['avatar']
            if not user.role:
                user.role = default_role
            user.save()

        # 生成JWT token
        # from rest_framework_simplejwt.tokens import RefreshToken # 导入 RefreshToken
        from rest_framework_simplejwt.tokens import RefreshToken # 导入 RefreshToken
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        refresh_token = str(refresh)

        # 构造用户信息
        user_info = {
            "userid": user.id,
            "username": user.username,
            "openid": mock_qq_user['openid'],
            "nickname": mock_qq_user['nickname'],
            "avatar": mock_qq_user['avatar']
        }

        # 返回登录成功页面，并自动跳转到前端首页
        html_content = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>QQ登录成功</title>
            <style>
                body {{
                    font-family: Arial, sans-serif;
                    text-align: center;
                    padding: 50px;
                    background-color: #f0f8ff;
                    margin: 0;
                }}
                .success-container {{
                    max-width: 400px;
                    margin: 0 auto;
                    padding: 30px;
                    background-color: white;
                    border-radius: 8px;
                    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                }}
                .success-icon {{
                    color: #28a745;
                    font-size: 48px;
                    margin-bottom: 20px;
                }}
                .user-info {{
                    margin: 20px 0;
                    padding: 15px;
                    background-color: #f8f9fa;
                    border-radius: 4px;
                }}
                .avatar {{
                    width: 60px;
                    height: 60px;
                    border-radius: 50%;
                    margin-bottom: 10px;
                }}
                .close-btn {{
                    background-color: #6c757d;
                    color: white;
                    padding: 10px 20px;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    margin-top: 20px;
                }}
                .close-btn:hover {{
                    background-color: #5a6268;
                }}
            </style>
        </head>
        <body>
            <div class="success-container">
                <div class="success-icon">✓</div>
                <h2>QQ登录成功！</h2>
                <div class="user-info">
                    <img src="{user_info['avatar']}" alt="头像" class="avatar">
                    <p><strong>用户名：</strong>{user_info['nickname']}</p>
                    <p><strong>OpenID：</strong>{user_info['openid']}</p>
                </div>
                <p>正在跳转到首页...</p>
                <button class="close-btn" onclick="goToHome()">立即跳转</button>
            </div>

            <script>
                // 保存用户信息到localStorage
                localStorage.setItem('qq_token', '{access_token}');
                localStorage.setItem('qq_refresh_token', '{refresh_token}');
                localStorage.setItem('qq_user_info', JSON.stringify({user_info}));

                // 2秒后自动跳转到前端首页
                setTimeout(() => {{
                    goToHome();
                }}, 2000);

                function goToHome() {{
                    try {{
                        // 跳转到前端首页，请根据您的实际前端地址修改
                        window.location.href = 'http://localhost:3000/';  // 修改为您的Vue项目地址
                    }} catch (e) {{
                        // 如果无法跳转，显示提示
                        document.body.innerHTML = '<div style="text-align:center;padding:50px;"><h2>登录成功！</h2><p>请手动返回首页。</p></div>';
                    }}
                }}
            </script>
        </body>
        </html>
        """

        return HttpResponse(html_content, content_type='text/html')


@method_decorator(csrf_exempt, name='dispatch')
class QQAutoLoginView(View):
    """QQ自动登录接口 - 前端调用此接口自动创建用户并登录"""

    def get(self, request):
        # 获取默认角色
        default_role = Role.objects.first()
        if not default_role:
            return JsonResponse({
                "error": "系统错误",
                "msg": "请先在后台创建至少一个角色"
            }, status=500)

        # 生成模拟QQ用户信息
        mock_qq_user = {
            'openid': f'qq_openid_{random.randint(10000, 99999)}',
            'nickname': f'QQ用户{random.randint(1000, 9999)}',
            'avatar': 'https://qlogo.cn/qqapp/102795359/default/100'
        }

        # 创建或获取用户
        user, created = User.objects.get_or_create(
            openid=mock_qq_user['openid'],
            defaults={
                'username': mock_qq_user['nickname'],
                'role': default_role,
                'avatar': mock_qq_user['avatar']
            }
        )

        # 如果用户已存在但信息不完整，更新信息
        if not created:
            if not user.username:
                user.username = mock_qq_user['nickname']
            if not user.avatar:
                user.avatar = mock_qq_user['avatar']
            if not user.role:
                user.role = default_role
            user.save()

        # 生成JWT token
        # from rest_framework_simplejwt.tokens import RefreshToken # 导入 RefreshToken
        from rest_framework_simplejwt.tokens import RefreshToken # 导入 RefreshToken
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        refresh_token = str(refresh)

        # 构造用户信息
        user_info = {
            "userid": user.id,
            "username": user.username,
            "openid": mock_qq_user['openid'],
            "nickname": mock_qq_user['nickname'],
            "avatar": mock_qq_user['avatar']
        }

        # 返回JSON格式的登录信息
        return JsonResponse({
            "success": True,
            "msg": "QQ登录成功",
            "user_info": user_info,
            "token": access_token,
            "refresh_token": refresh_token
        })


# ========== 钉钉第三方登录 ==========
# 获取url地址跳转钉钉授权页面->钉钉回调首页->获取code->获取用户token->获取用户信息->
# 1.点击获取钉钉登录URL  点击钉钉图片跳转到登录授权页面
class DDGetUrl(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        # 生成随机状态码，防止CSRF攻击
        state = str(uuid.uuid4())
        request.session['dingtalk_state'] = state

        # 构建钉钉授权URL
        redirect_uri = "http://localhost:8000/user/dd_callback/"  # 回调地址-下一个接口
        # 钉钉应用配置
        DINGTALK_APPID = 'dinglyrgo3vzh4tgz09p'  # 钉钉开放平台应用ID  APPKey

        url = f"https://login.dingtalk.com/oauth2/auth?redirect_uri={redirect_uri}&response_type=code&client_id={DINGTALK_APPID}&scope=openid corpid&state={state}&prompt=consent"
        # url=f"https://login.dingtalk.com/oauth2/auth?redirect_uri=http://localhost:8000/user/callback/&response_type=code&client_id=dinglyrgo3vzh4tgz09p&scope=openid corpid&state=state&prompt=consent"
        return safe_response({"code": 200, "msg": '获取成功！', "url": url})


# 2.回调接口-获取用户信息。
# 当用户同意授权之后，钉钉会返回code参数 重定向到回调地址，通过code参数获取用户信息access_token
class DDCallback(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        # 获取前端参数code
        code = request.query_params.get('code')
        if not code:
            return safe_response('/?error=钉钉授权失败')
        url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"

        # 根据code获取用户accessToken
        data = {
            "clientId": "dinglyrgo3vzh4tgz09p",
            "clientSecret": "qv3DPWXqcxr0mSv9B6S2eaExQth7TdxMBzSd4gdemXEKlEPJaJ4th7jtb4ubwwdc",
            "code": code,
            "grantType": "authorization_code"
        }
        response = requests.post(url, json=data).json()
        print("钉钉返回：", response)  # 调试用

        # 使用 code 向钉钉服务器请求 accessToken
        if "accessToken" not in response:
            return safe_response({"code": 500, "msg": "钉钉授权失败", "detail": response})
        accessToken = response["accessToken"]
        # uid = response["openId"]

        # 根据accessToken获取用户信息
        user_info_url = "https://api.dingtalk.com/v1.0/contact/users/me"
        headers = {"x-acs-dingtalk-access-token": accessToken}
        user_info = requests.get(user_info_url, headers=headers).json()
        print("钉钉用户信息：", user_info)

        if "openId" not in user_info:
            return safe_response({"code": 500, "msg": "获取钉钉用户信息失败", "detail": user_info})

        uid = user_info["openId"]
        name = user_info.get('nick')
        phone = user_info.get('mobile')

        # 登录 获取第三方登录表 和 用户表
        third = models.ThirdLogin.objects.filter(oauth_id=uid, style='dingding').first()  # oauth_id第三方登录id
        if not third:
            # 写入用户表  手机号用户存在直接绑定  手机号不存在则创建用户
            user = models.User.objects.filter(phone=phone).first()
            if not user:
                userinfo = {
                    "phone": phone,
                    "role": 1
                }
                u = userser.UserSerializer(data=userinfo)
                if u.is_valid():
                    user = u.save()
                else:
                    print(u.errors)  # 打印验证错误信息
                    return safe_response({"code": 500, "msg": '用户创建失败', "errors": u.errors})
            # 写入第三方登录表
            thinfo = {
                "oauth_id": uid,
                "style": "dingding",
                "token": accessToken,
                "userid": user.id
            }
            t = userser.ThirdLoginSerializer(data=thinfo)
            if t.is_valid():
                t.save()
            else:
                return safe_response({"code": 500, "msg": '第三方登录创建失败'})
        else:
            user = third.userid
            user.token = accessToken
            user.save()

        # 生成jwt token并返回前端
        payload = {"user_id": user.id}
        token = jwtTool.generate_token(payload)
        payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        refreshToken = jwtTool.generate_token(payload)
        # 这里改为重定向
        redirect_url = "http://localhost:5173/home/"
        return HttpResponseRedirect(redirect_url)


# 具体实现类 dingding  gitee
class GiteeUrl(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        """跳转到Gitee授权页面"""
        clientID = "98c2a9affee7aa2cd9dcbe2f74ee91f0a7345374a4c2cc029c6fdf2828607f8b"
        # clientSecret = "8953980345edb1881de15b177a93dfd38709e5585fc930b1eff3f8ea215588b1"
        clientURL = 'http://localhost:8000/user/git_callback/'  # 统一用localhost
        # 生成随机state防止CSRF攻击
        state = str(uuid.uuid4())
        request.session['gitee_auth_state'] = state

        # 构造授权URL
        auth_url = (
            f"https://gitee.com/oauth/authorize?"
            f"client_id={clientID}&"
            f"redirect_uri={clientURL}&"
            f"response_type=code&"
            f"state={state}"
        )
        return safe_response({"code": 200, "msg": '获取成功！', "url": auth_url})


class GiteeCallback(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        code = request.GET.get('code')
        if not code:
            return safe_response("授权失败，未获取到授权码", status=400)

        # 1. 获取 access_token
        token_url = 'https://gitee.com/oauth/token'
        data = {
            'grant_type': 'authorization_code',
            'code': code,
            'client_id': "98c2a9affee7aa2cd9dcbe2f74ee91f0a7345374a4c2cc029c6fdf2828607f8b",
            'client_secret': "8953980345edb1881de15b177a93dfd38709e5585fc930b1eff3f8ea215588b1",
            'redirect_uri': "http://localhost:8000/user/git_callback/",
        }
        response = requests.post(token_url, data=data)
        response.raise_for_status()
        token_data = response.json()
        access_token = token_data.get('access_token')
        if not access_token:
            return safe_response("获取 access_token 失败", status=400)

        # 2. 获取 Gitee 用户信息
        user_info_url = f'https://gitee.com/api/v5/user?access_token={access_token}'
        user_response = requests.get(user_info_url)
        user_response.raise_for_status()
        user_data = user_response.json()
        gitee_id = user_data.get('id')
        gitee_login = user_data.get('login')
        gitee_name = user_data.get('name') or gitee_login
        gitee_avatar = user_data.get('avatar_url')

        # 3. 查找/创建本地用户
        third = models.ThirdLogin.objects.filter(oauth_id=gitee_id, style='gitee').first()
        if not third:
            user = models.User.objects.filter(phone=None).first()  # Gitee没有手机号
            if not user:
                userinfo = {
                    "phone": str(gitee_login),  # 用gitee_login或gitee_id填充
                    "role": 1,
                    "username": gitee_name
                }
                u = userser.UserSerializer(data=userinfo)
                if u.is_valid():
                    user = u.save()
                else:
                    print(u.errors)
                    return safe_response({"code": 500, "msg": '用户创建失败', "errors": u.errors})
            thinfo = {
                "oauth_id": gitee_id,
                "style": "gitee",
                "token": access_token,
                "userid": user.id
            }
            t = userser.ThirdLoginSerializer(data=thinfo)
            if t.is_valid():
                t.save()
            else:
                return safe_response({"code": 500, "msg": '第三方登录创建失败'})
        else:
            user = third.userid
            user.token = access_token
            user.save()

        # 4. 生成token并重定向
        payload = {"user_id": user.id}
        token = jwtTool.generate_token(payload)
        payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        refreshToken = jwtTool.generate_token(payload)
        redirect_url = "http://localhost:5173/home/"
        return HttpResponseRedirect(redirect_url)


from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name='dispatch')  # 处理跨域请求伪造
class QiniuUpload(APIView):
    def post(self, request):
        """
        统一处理两种请求：
        1. 前端主动上传文件（带 file 参数）
        2. 七牛云上传完成后的回调（带 filename/filesize 等参数）
        """
        # 区分请求类型：前端上传（有 file） vs 七牛云回调（无 file，有 filename）
        if 'file' in request.FILES:
            return self.handle_frontend_upload(request)
        else:
            return self.handle_qiniu_callback(request)

    def handle_frontend_upload(self, request):
        """处理前端主动上传文件逻辑"""
        # 1. 提取核心参数
        file_obj = request.FILES['file']
        file_type = request.data.get('type', 'resume')
        # userid = request.data.get('userid')
        userid=models.User.objects.get(id=1).id

        # 2. 极简参数校验
        if not all([file_obj, userid]):
            return Response(
                {'error': '缺少文件或用户ID'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 3. 文件类型校验（复用 models 定义）
        if file_type not in dict(models.UserFile.file_type.field.choices).keys():
            return Response(
                {'error': '文件类型只能是 idcard 或 resume'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 4. 生成七牛云存储 Key
        file_ext = os.path.splitext(file_obj.name)[1]
        key = f"{int(time.time()*1000)}_{uuid.uuid4().hex[:8]}{file_ext}"

        # 5. 执行七牛云上传（使用带回调策略的 token）
        qiniu_token=tool_qiniu.get_token_with_policy(key)
        qiniu_domain=tool_qiniu.domain

        try:
            ret, info = put_data(qiniu_token, key, file_obj.read())
            if info.status_code != 200:
                return Response(
                    {'error': f'七牛云上传失败: {info.error}'},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR
                )
        except Exception as e:
            return Response(
                {'error': f'上传异常: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

        # 6. 关联用户并写入数据库
        file_url = f"http://{qiniu_domain}/{key}"
        try:
            user = User.objects.get(id=userid)
            models.UserFile.objects.create(
                user=user,
                file_url=file_url,
                file_name=file_obj.name,
                file_type=file_type
            )
        except User.DoesNotExist:
            return Response(
                {'error': '用户不存在'},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            return Response(
                {'error': f'数据库错误: {str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

        # 7. 返回极简成功响应
        return Response(
            {'success': True, 'file_key': key,'url': file_url, 'message': '文件上传成功'},
            status=status.HTTP_201_CREATED
        )

    def handle_qiniu_callback(self, request):
        """处理七牛云上传完成后的回调逻辑，移除文件大小更新冗余部分"""
        # 1. 提取关键回调参数（仅保留用于匹配文件记录的 key）
        key = request.data.get('key')  # 七牛云存储的文件 Key，用于关联数据库记录
        if not key:
            return Response(
                {'error': '缺少七牛云文件 Key 参数，无法关联文件记录'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 2. 根据 key 查找文件记录
        try:
            file_record = models.UserFile.objects.filter(file_url__contains=key).first()
            if file_record:
                # 若找到记录，可根据实际需求补充其他必要操作（如无需更新字段，直接返回成功）
                return Response(
                    {'status': '回调处理成功，文件记录已关联'},
                    status=status.HTTP_200_OK
                )
            return Response(
                {'error': '未找到对应文件记录'},
                status=status.HTTP_404_NOT_FOUND
            )

        except Exception as e:
            return Response(
                {'error': f'回调处理失败：{str(e)}'},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )



@method_decorator(csrf_exempt, name='dispatch')
class IDCardUploadView(APIView):
    """身份证图片上传视图"""

    def post(self, request):
        try:
            front_image = request.FILES.get('front_image')
            back_image = request.FILES.get('back_image')
            user_id = request.data.get('user_id')
            print(f"收到 user_id: {user_id}")
            if not front_image and not back_image:
                return safe_response({'code': 400, 'msg': '请至少上传一张身份证图片'})
            result_data = {}
            front_url = None
            back_url = None
            if front_image:
                front_result = image_uploader.upload_image(front_image, file_type='id_card', storage_type='local')
                print('front_result:', front_result, type(front_result))  # 调试打印
                if isinstance(front_result, str):
                    try:
                        front_result = json.loads(front_result)
                    except Exception:
                        return safe_response({'code': 400, 'msg': f'正面图片上传失败: {front_result}'})
                if not isinstance(front_result, dict):
                    return safe_response({'code': 400, 'msg': f'正面图片上传失败: 非法返回类型', 'detail': str(front_result)})
                if front_result.get('success'):
                    front_url = front_result.get('url', '')
                    result_data['front_image_url'] = front_url
                    # 自动提取身份证头像，增强异常捕获和日志
                    front_file_path = front_result.get('file_path')
                    if front_file_path:
                        try:
                            face_result = baidu_ai.extract_face_from_idcard(front_file_path)
                            print(f"extract_face_from_idcard result: {face_result}")
                        except Exception as e:
                            import traceback
                            print(f"extract_face_from_idcard error: {e}")
                            print(traceback.format_exc())
                else:
                    error_msg = front_result['error'] if isinstance(front_result, dict) and 'error' in front_result else str(front_result)
                    return safe_response({'code': 400, 'msg': f'正面图片上传失败: {error_msg}'})
            if back_image:
                back_result = image_uploader.upload_image(back_image, file_type='id_card', storage_type='local')
                print('back_result:', back_result, type(back_result))  # 调试打印
                if isinstance(back_result, str):
                    try:
                        back_result = json.loads(back_result)
                    except Exception:
                        return safe_response({'code': 400, 'msg': f'背面图片上传失败: {back_result}'})
                if not isinstance(back_result, dict):
                    return safe_response({'code': 400, 'msg': f'背面图片上传失败: 非法返回类型', 'detail': str(back_result)})
                if back_result.get('success'):
                    back_url = back_result.get('url', '')
                    result_data['back_image_url'] = back_url
                else:
                    error_msg = back_result['error'] if isinstance(back_result, dict) and 'error' in back_result else str(back_result)
                    return safe_response({'code': 400, 'msg': f'背面图片上传失败: {error_msg}'})
            # 自动写入实名认证表
            if user_id and front_url and back_url:
                try:
                    # 兼容 user_id 为字符串或数字
                    user = None
                    try:
                        user = User.objects.get(id=int(user_id))
                    except Exception:
                        user = User.objects.filter(id=user_id).first()
                    print(f"自动写入实名认证表: user_id={user_id}, front={front_url}, back={back_url}")
                    if user:
                        # 检查是否已存在待审核的记录
                        existing_verification = RealNameVerification.objects.filter(
                            user=user, verification_status=0
                        ).first()
                        
                        if existing_verification:
                            # 更新现有记录
                            existing_verification.id_card_front = front_url
                            existing_verification.id_card_back = back_url
                            existing_verification.save()
                            print(f"更新现有实名认证记录: {existing_verification.id}")
                        else:
                            # 创建新记录，使用NULL而不是空字符串
                            verification = RealNameVerification.objects.create(
                                user=user,
                                real_name=None,  # 使用NULL而不是空字符串
                                id_card_number=None,  # 使用NULL而不是空字符串
                                id_card_front=front_url,
                                id_card_back=back_url,
                                verification_status=0
                            )
                            print(f"创建新实名认证记录: {verification.id}")
                    else:
                        print(f"未找到 user_id={user_id} 的用户，无法写入实名认证表")
                except Exception as e:
                    print(f"实名认证表写入失败: {e}")
                    import traceback
                    print(traceback.format_exc())
            # 返回前再做一次类型检查
            response_data = {'code': 200, 'msg': '身份证图片上传成功', 'data': result_data}
            if isinstance(response_data, str):
                try:
                    response_data = json.loads(response_data)
                except Exception:
                    response_data = {'code': 500, 'msg': '返回数据格式错误'}
            return safe_response(response_data)
        except Exception as e:
            print(f"身份证图片上传接口异常: {e}")
            return safe_response({'code': 500, 'msg': f'系统错误: {str(e)}'})


class RealNameVerificationView(APIView):
    """实名认证视图"""

    def post(self, request):
        user_id = request.data.get('user_id')
        id_card_front_url = request.data.get('id_card_front_url')
        id_card_back_url = request.data.get('id_card_back_url')
        if not all([user_id, id_card_front_url, id_card_back_url]):
            return safe_response({'code': 400, 'msg': '请提供完整的认证信息：用户ID、身份证正反面图片URL'})
        try:
            user = User.objects.get(id=user_id)
            if user.is_verified:
                return safe_response({'code': 400, 'msg': '用户已完成实名认证'})
            existing_verification = RealNameVerification.objects.filter(user=user, verification_status=0).first()
            if existing_verification:
                return safe_response({'code': 400, 'msg': '您已有待审核的认证申请，请耐心等待'})
            verification = RealNameVerification.objects.create(
                user=user,
                real_name='',
                id_card_number='',
                id_card_front=id_card_front_url,
                id_card_back=id_card_back_url,
                verification_status=0
            )
            queue_data = {
                'verification_id': verification.id,
                'user_id': user_id,
                'front_image_url': id_card_front_url,
                'back_image_url': id_card_back_url,
                'created_at': timezone.now().isoformat()
            }
            queue_key = f"verification_queue_{verification.id}"
            myRedis.set(queue_key, json.dumps(queue_data), 3600)
            myRedis.lpush('verification_queue', verification.id)
            return safe_response({'code': 200, 'msg': '实名认证申请已提交，正在处理中，请等待', 'data': {'verification_id': verification.id, 'status': 'processing'}})
        except Exception as e:
            return safe_response({'code': 500, 'msg': f'系统错误: {str(e)}'})


class RealNameVerificationStatusView(APIView):
    """查询实名认证状态"""

    def get(self, request):
        user_id = request.query_params.get('user_id')
        if not user_id:
            return safe_response({'code': 400, 'msg': '用户ID不能为空'})
        try:
            user = User.objects.get(id=user_id)
            verification = RealNameVerification.objects.filter(user=user).order_by('-created_at').first()
            if not verification:
                return safe_response({'code': 200, 'msg': '暂无认证记录', 'data': {'is_verified': False, 'verification_status': None, 'verification_info': None}})
            status_map = {0: '待审核', 1: '审核通过', 2: '审核拒绝'}
            return safe_response({'code': 200, 'msg': '查询成功', 'data': {
                'is_verified': user.is_verified,
                'verification_status': verification.verification_status,
                'verification_status_text': status_map.get(verification.verification_status, '未知'),
                'verification_info': {
                    'real_name': verification.real_name,
                    'id_card_number': verification.id_card_number[:6] + '****' + verification.id_card_number[
                                                                                 -4:] if verification.id_card_number else '',
                    'created_at': verification.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                    'verified_at': verification.verified_at.strftime(
                        '%Y-%m-%d %H:%M:%S') if verification.verified_at else None,
                    'reject_reason': verification.reject_reason
                }
            }})
        except User.DoesNotExist:
            return safe_response({'code': 400, 'msg': '用户不存在'})
        except Exception as e:
            return safe_response({'code': 500, 'msg': f'系统错误: {str(e)}'})


@api_view(['GET'])
def get_verification_result(request):
    try:
        image_url = request.GET.get('image_url')
        if not image_url:
            return safe_response({'success': False, 'message': '图片地址不能为空'}, status=400)
        redis_client = RedisClient()
        result_data = redis_client.get_string(image_url)
        if result_data:
            try:
                result = json.loads(result_data)
                if isinstance(result, dict) and 'name' in result and 'code' in result:
                    return safe_response({'success': True, 'message': '获取识别结果成功', 'data': result})
                else:
                    return safe_response({'success': False, 'message': '识别结果数据格式错误'}, status=500)
            except json.JSONDecodeError:
                return safe_response({'success': False, 'message': '识别结果数据格式错误'}, status=500)
        else:
            return safe_response({'success': False, 'message': '没找到', 'data': None})
    except Exception as e:
        return safe_response({'success': False, 'message': f'查询失败: {str(e)}'}, status=500)

def get_local_path(relative_path):
    """将相对路径（如 /uploads/id_card/xxx.png）拼接为本地绝对路径"""
    if relative_path.startswith('/'):
        relative_path = relative_path[1:]
    return os.path.join(settings.MEDIA_ROOT, relative_path)


@api_view(['POST'])
def id_card_ocr(request):
    """身份证图片识别接口，返回姓名和身份证号，便于前端自动填充"""
    try:
        image = request.FILES.get('image')
        if not image:
            return safe_response({'success': False, 'message': '请上传身份证图片'}, status=400)
        upload_result = image_uploader.upload_image(image, file_type='id_card', storage_type='local')
        print('upload_result:', upload_result, type(upload_result))  # 新增打印
        if isinstance(upload_result, str):
            try:
                upload_result = json.loads(upload_result)
            except Exception:
                return safe_response({'success': False, 'message': str(upload_result)}, status=400)
        if not isinstance(upload_result, dict) or not upload_result.get('success'):
            error_msg = upload_result['error'] if isinstance(upload_result, dict) and 'error' in upload_result else str(upload_result)
            return safe_response({'success': False, 'message': f"图片上传失败: {error_msg}"}, status=400)
        image_url = upload_result['url']
        image_path = upload_result.get('file_path')  # 本地绝对路径

        # 新增：提取身份证头像
        face_url = None
        if image_path:
            face_result = baidu_ai.extract_face_from_idcard(image_path)
            print('face_result:', face_result)
            if face_result.get('success') and face_result.get('face_path'):
                import os
                face_path = face_result['face_path']
                face_url = '/uploads/id_card/' + os.path.basename(face_path)

        # 调用百度AI身份证识别
        ocr_result = baidu_ai.verify_id_card(image_url, side='front')
        print('ocr_result:', ocr_result, type(ocr_result))  # 新增打印
        if isinstance(ocr_result, str):
            try:
                ocr_result = json.loads(ocr_result)
            except Exception:
                return safe_response({'success': False, 'message': str(ocr_result), 'path': image_url}, status=200)
        if not isinstance(ocr_result, dict):
            return safe_response({'success': False, 'message': '识别服务返回格式错误', 'path': image_url}, status=200)
        if ocr_result.get('success'):
            data = ocr_result.get('data') or {}
            name = data.get('name', '')
            code = data.get('id_number', '')
            words_list = []
            if name:
                words_list.append(f"姓名{name}")
            if code:
                words_list.append(f"身份证号{code}")
            resp = {'success': True, 'words_list': words_list, 'path': image_url, 'face_url': face_url}  # 返回头像URL
            print('final response:', resp, type(resp))  # 新增打印
            return safe_response(resp)
        else:
            error_msg = ocr_result.get('error_msg', '识别失败')
            resp = {'success': False, 'message': error_msg, 'path': image_url, 'face_url': face_url}  # 返回头像URL
            print('final response:', resp, type(resp))  # 新增打印
            return safe_response(resp, status=200)
    except Exception as e:
        import traceback
        print(traceback.format_exc())
        return safe_response({'success': False, 'message': str(e)}, status=500)


def safe_response(data, status=200):
    if isinstance(data, str):
        try:
            data = json.loads(data)
        except Exception:
            data = {"error": data}
    return Response(data, status=status)


# ========== 新增用户认证API ==========

class UserLoginAPIView(APIView):
    """用户登录API"""
    permission_classes = [AllowAny]
    
    def post(self, request):
        try:
            serializer = userser.UserLoginSerializer(data=request.data)
            if not serializer.is_valid():
                return safe_response({'code': 400, 'msg': '参数错误', 'errors': serializer.errors}, status=400)
            
            username = serializer.validated_data['username']
            password = serializer.validated_data['password']
            
            # 查找用户（支持用户名、手机号或邮箱登录）
            user = models.User.objects.filter(
                Q(username=username) | 
                Q(phone=username) | 
                Q(email=username)
            ).first()
            
            if not user:
                return safe_response({'code': 400, 'msg': '用户不存在'}, status=400)
            
            # 明文密码校验（仅测试用，生产环境请加密）
            if user.password_hash and user.password_hash != password:
                return safe_response({'code': 400, 'msg': '密码错误'}, status=400)
            
            # 生成JWT token
            token = jwtTool.generate_token(user.id)
            
            # 返回用户信息
            user_data = userser.UserProfileSerializer(user).data
            
            return safe_response({
                'code': 200, 
                'msg': '登录成功',
                'data': {
                    'token': token,
                    'user': user_data
                }
            })
        except Exception as e:
            import traceback
            print(traceback.format_exc())
            return safe_response({'code': 500, 'msg': '服务器异常', 'detail': str(e)}, status=500)


class UserProfileAPIView(APIView):
    """获取用户信息API"""
    permission_classes = [AllowAny]
    def get(self, request):
        # 兼容性获取token
        auth_header = request.headers.get('Authorization') or request.META.get('HTTP_AUTHORIZATION')
        if not auth_header or not auth_header.startswith('Bearer '):
            print('未提供认证token或格式错误', auth_header)
            return safe_response({'code': 401, 'msg': '未提供认证token'}, status=401)
        
        token = auth_header.split(' ')[1]
        
        try:
            # 验证token
            try:
                payload = jwtTool.decode_token(token)
            except Exception as e:
                print('token解析失败', e)
                return safe_response({'code': 401, 'msg': 'token验证失败'}, status=401)
            user_id = payload.get('user_id')
            
            if not user_id:
                print('token无user_id', payload)
                return safe_response({'code': 401, 'msg': 'token无效'}, status=401)
            
            # 获取用户信息
            user = models.User.objects.filter(id=user_id).first()
            if not user:
                print('用户不存在', user_id)
                return safe_response({'code': 404, 'msg': '用户不存在'}, status=404)
            
            user_data = userser.UserProfileSerializer(user).data
            
            return safe_response({
                'code': 200,
                'msg': '获取成功',
                'data': user_data
            })
            
        except Exception as e:
            print('服务器异常', e)
            return safe_response({'code': 500, 'msg': '服务器异常', 'detail': str(e)}, status=500)


class UserActionsAPIView(APIView):
    """获取用户操作状态API"""
    
    def get(self, request):
        user_id = request.query_params.get('user_id')
        if not user_id:
            return safe_response({'code': 400, 'msg': '缺少user_id参数'}, status=400)
        
        try:
            user_id = int(user_id)
        except ValueError:
            return safe_response({'code': 400, 'msg': 'user_id必须是整数'}, status=400)
        
        # 获取用户点赞的帖子
        liked_posts = {}
        user_likes = PostLike.objects.filter(user_id=user_id)
        for like in user_likes:
            liked_posts[str(like.post_id)] = True
        
        # 获取用户收藏的帖子
        starred_posts = {}
        user_stars = PostStar.objects.filter(user_id=user_id)
        for star in user_stars:
            starred_posts[str(star.post_id)] = True
        
        return safe_response({
            'code': 200,
            'msg': '获取成功',
            'data': {
                'liked_posts': liked_posts,
                'starred_posts': starred_posts
            }
        })


class UserActionsSyncAPIView(APIView):
    """同步用户操作API"""
    
    def post(self, request):
        serializer = posts.serializers.UserActionSyncSerializer(data=request.data)
        if not serializer.is_valid():
            return safe_response({'code': 400, 'msg': '参数错误', 'errors': serializer.errors}, status=400)
        
        user_id = serializer.validated_data['user_id']
        actions = serializer.validated_data['actions']
        
        synced_count = 0
        
        # 同步点赞状态
        if 'liked_posts' in actions:
            for post_id, is_liked in actions['liked_posts'].items():
                try:
                    post_id = int(post_id)
                    if is_liked:
                        # 添加点赞
                        PostLike.objects.get_or_create(user_id=user_id, post_id=post_id)
                    else:
                        # 取消点赞
                        PostLike.objects.filter(user_id=user_id, post_id=post_id).delete()
                    synced_count += 1
                except (ValueError, Post.DoesNotExist):
                    continue
        
        # 同步收藏状态
        if 'starred_posts' in actions:
            for post_id, is_starred in actions['starred_posts'].items():
                try:
                    post_id = int(post_id)
                    if is_starred:
                        # 添加收藏
                        PostStar.objects.get_or_create(user_id=user_id, post_id=post_id)
                    else:
                        # 取消收藏
                        PostStar.objects.filter(user_id=user_id, post_id=post_id).delete()
                    synced_count += 1
                except (ValueError, Post.DoesNotExist):
                    continue
        
        return safe_response({
            'code': 200,
            'msg': '同步成功',
            'data': {
                'success': True,
                'synced_count': synced_count
            }
        })


@csrf_exempt
@api_view(['POST'])
@permission_classes([AllowAny])
def face_compare(request):
    """人脸对比接口，接收自拍照和user_id，与身份证头像比对"""
    user_id = request.data.get('user_id')
    face_image = request.FILES.get('face_image')
    if not user_id or not face_image:
        print(f"face_compare user_id: {user_id}")
        print(f"face_compare face_image: {face_image}")
        print("face_compare: 缺少参数")
        return Response({'success': False, 'msg': '缺少参数'}, status=400)
    # 保存自拍照
    upload_result = image_uploader.upload_image(face_image, file_type='face', storage_type='local')
    if not upload_result.get('success'):
        print(f"face_compare user_id: {user_id}")
        print(f"face_compare upload_result: {upload_result}")
        print("face_compare: 自拍照上传失败")
        return Response({'success': False, 'msg': '自拍照上传失败'}, status=400)
    selfie_path = upload_result['file_path']
    print(f"face_compare user_id: {user_id}")
    verification = RealNameVerification.objects.filter(user_id=user_id).order_by('-created_at').first()
    print(f"face_compare verification: {verification}")
    idcard_face_path = None
    if verification and verification.id_card_front:
        front_filename = os.path.basename(verification.id_card_front)
        base, ext = os.path.splitext(front_filename)
        face_filename = base + '_face' + ext
        idcard_face_path = os.path.join(settings.MEDIA_ROOT, 'id_card', face_filename)
        print(f"face_compare id_card_front: {verification.id_card_front}")
        print(f"face_compare front_filename: {front_filename}")
        print(f"face_compare face_filename: {face_filename}")
        print(f"face_compare idcard_face_path: {idcard_face_path}")
        print(f"face_compare exists: {os.path.exists(idcard_face_path)}")
    else:
        print(f"face_compare: 未查到实名认证记录或正面图片")
        return Response({'success': False, 'msg': '未查到实名认证记录或正面图片'}, status=400)
    if not idcard_face_path or not os.path.exists(idcard_face_path):
        print(f"face_compare idcard_face_path: {idcard_face_path}")
        print(f"face_compare exists: {os.path.exists(idcard_face_path)}")
        print("face_compare: 身份证头像不存在")
        return Response({'success': False, 'msg': '身份证头像不存在', 'debug_path': idcard_face_path}, status=400)
    # 人脸对比
    result = baidu_ai.face_match(idcard_face_path, selfie_path)
    if result['success']:
        score = result['score']
        return Response({'success': True, 'score': score, 'msg': '对比成功' if score > 80 else '人脸不一致'})
    else:
        print(f"face_compare: 人脸对比失败 {result}")
        return Response({'success': False, 'msg': result['msg']})


# 根据传回来的userid 查询用户信息
class UserInfoAPIView(APIView):
    """用户信息API"""
    def post(self,request):
        userid = request.data.get('userid')
        userdata = models.User.objects.filter(id=userid).first()
        res = userser.UserSerializer(userdata).data.get('role')
        if res == 2:
            res = userser.HRInfoSerializer(models.HRInfo.objects.filter(user_id=userid).first()).data
        elif res == 1:
            res = userser.JobInfoSerializer(models.JobInfo.objects.filter(user_id=userid).first()).data
        else:
            res = userser.UserSerializer(models.User.objects.filter(id=userid).first()).data
        return Response({'code':200,'data':res})



from rest_framework import status

class JobInfoAPIView(APIView):
    """求职者信息操作API"""

    def post(self, request):
        """修改求职者信息"""
        userid = request.data.get('userid')
        try:
            job_info = models.JobInfo.objects.get(user_id=userid)
            serializer = userser.JobInfoSerializer(job_info, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'code': 200, 'msg': '求职者信息更新成功', 'data': serializer.data})
            return Response({'code': 400, 'msg': '数据验证失败', 'errors': serializer.errors},
                            status=status.HTTP_400_BAD_REQUEST)
        except models.JobInfo.DoesNotExist:
            return Response({'code': 404, 'msg': '求职者信息不存在'}, status=status.HTTP_404_NOT_FOUND)

    def delete(self, request):
        """删除求职者信息"""
        userid = request.data.get('userid')
        try:
            job_info = models.JobInfo.objects.get(user_id=userid)
            job_info.delete()
            return Response({'code': 200, 'msg': '求职者信息删除成功'})
        except models.JobInfo.DoesNotExist:
            return Response({'code': 404, 'msg': '求职者信息不存在'}, status=status.HTTP_404_NOT_FOUND)


class WorkExperienceAPIView(APIView):
    """工作经历操作API"""

    def post(self, request):
        """修改工作经历"""
        experience_id = request.data.get('id')
        try:
            work_exp = models.WorkExperience.objects.get(id=experience_id)
            serializer = userser.WorkExperienceSerializer(work_exp, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'code': 200, 'msg': '工作经历更新成功', 'data': serializer.data})
            return Response({'code': 400, 'msg': '数据验证失败', 'errors': serializer.errors},
                            status=status.HTTP_400_BAD_REQUEST)
        except models.WorkExperience.DoesNotExist:
            return Response({'code': 404, 'msg': '工作经历不存在'}, status=status.HTTP_404_NOT_FOUND)

    def delete(self, request):
        """删除工作经历"""
        experience_id = request.data.get('id')
        try:
            work_exp = models.WorkExperience.objects.get(id=experience_id)
            work_exp.delete()
            return Response({'code': 200, 'msg': '工作经历删除成功'})
        except models.WorkExperience.DoesNotExist:
            return Response({'code': 404, 'msg': '工作经历不存在'}, status=status.HTTP_404_NOT_FOUND)


class AddWorkExperienceAPIView(APIView):
    """添加个人工作经历API"""

    def post(self, request):
        # 获取前端传回的JobInfo ID和工作经历数据
        job_info_id = request.data.get('job_info_id')
        work_experience_data = request.data.get('work_experience', {})

        # 验证JobInfo是否存在
        try:
            job_info = models.JobInfo.objects.get(id=job_info_id)
        except models.JobInfo.DoesNotExist:
            return Response({
                'code': 404,
                'message': '未找到对应的求职者信息',
                'errors': f'JobInfo with id {job_info_id} does not exist'
            }, status=status.HTTP_404_NOT_FOUND)

        # 准备要保存的数据
        data_to_save = {
            'job_info': job_info.id,
            'company': work_experience_data.get('company'),
            'position': work_experience_data.get('position'),
            'start_date': work_experience_data.get('start_date'),
            'end_date': None if work_experience_data.get('is_current') else work_experience_data.get('end_date'),
            'description': work_experience_data.get('description'),
            'salary_range': work_experience_data.get('salary_range'),
            'industry': work_experience_data.get('industry')
        }

        # 序列化并验证数据
        serializer = userser.WorkExperienceSerializer(data=data_to_save)
        if serializer.is_valid():
            serializer.save()
            return Response({
                'code': 200,
                'message': '工作经历添加成功',
                'data': serializer.data
            }, status=status.HTTP_201_CREATED)

        # 返回详细的错误信息
        return Response({
            'code': 400,
            'message': '数据验证失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)


from django.core.files.storage import default_storage
from django.conf import settings
import os
import uuid


class UploadAvatarAPIView(APIView):
    """上传用户头像API"""

    def post(self, request):
        # 获取用户ID和上传的文件
        user_id = request.data.get('userid')
        avatar_file = request.FILES.get('avatar')

        if not user_id:
            return Response({
                'code': 400,
                'message': '用户ID不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        if not avatar_file:
            return Response({
                'code': 400,
                'message': '请选择要上传的头像文件'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 验证文件类型
        allowed_types = ['image/jpeg', 'image/png', 'image/gif']
        if avatar_file.content_type not in allowed_types:
            return Response({
                'code': 400,
                'message': '只支持JPEG、PNG或GIF格式的图片'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 验证文件大小 (限制为2MB)
        max_size = 2 * 1024 * 1024  # 2MB
        if avatar_file.size > max_size:
            return Response({
                'code': 400,
                'message': '头像文件大小不能超过2MB'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 获取用户JobInfo记录
            job_info = models.JobInfo.objects.get(user_id=user_id)

            # 生成唯一文件名
            ext = os.path.splitext(avatar_file.name)[1]  # 获取文件扩展名
            filename = f"{uuid.uuid4().hex}{ext}"  # 使用UUID生成唯一文件名

            # 构建存储路径
            upload_path = os.path.join('user', filename)
            full_path = os.path.join(settings.MEDIA_ROOT, upload_path)

            # 保存文件
            with default_storage.open(full_path, 'wb+') as destination:
                for chunk in avatar_file.chunks():
                    destination.write(chunk)

            # 构建完整的URL
            avatar_url = f"http://127.0.0.1:8000{settings.MEDIA_URL}{upload_path}"

            # 更新数据库
            job_info.aveter = avatar_url
            job_info.save()

            return Response({
                'code': 200,
                'message': '头像上传成功',
                'data': {
                    'avatar_url': avatar_url
                }
            }, status=status.HTTP_200_OK)

        except models.JobInfo.DoesNotExist:
            return Response({
                'code': 404,
                'message': '未找到用户信息'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            # 如果出错，删除可能已经上传的文件
            if 'full_path' in locals() and os.path.exists(full_path):
                os.remove(full_path)
            return Response({
                'code': 500,
                'message': '头像上传失败',
                'error': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)





